package org.swift.mashup.engine.deployment;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.xml.stream.XMLStreamException;
import java.io.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MashupVariablePreprocessor implements MashupPreprocessor {
	private static final Log log = LogFactory.getLog(MashupVariablePreprocessor.class);

	private static final Pattern PROPERTY_PATTERN = Pattern.compile("(\\#\\{([^\\}]+)\\})");
	private static final int PROPERTY_GROUP_PLACEHOLDER = 1;
	private static final int PROPERTY_GROUP_KEY = 2;

	public InputStream processMashup(final InputStream original, final String name)
			throws XMLStreamException, IOException {

		try {
			final File newMashupFile = getNewFile(name);
			processProperties(original, newMashupFile);
			return new FileInputStream(newMashupFile);
		}
		catch (IOException e) {
			log.error(String.format("Error while preprocessing %s : %s", name, e.getMessage()), e);
			throw e;
		}
	}

	protected File getNewFile(String mashupName) throws IOException {
		final File newMashupFile = File.createTempFile(mashupName, ".mux");
		newMashupFile.deleteOnExit();
		return newMashupFile;
	}

	public static void processProperties(InputStream in, File out) throws IOException {
		BufferedReader reader = null;
		BufferedWriter writer = null;

		try {
			reader = new BufferedReader(new InputStreamReader(in));
			writer = new BufferedWriter(new FileWriter(out));

			String line;
			while ( null != (line = reader.readLine()) ) {
				writer.write(resolveProperties(line));
				writer.newLine();
			}
		}
		finally {
			close(writer);
			close(reader);
		}
	}

	public static String resolveProperties(String str) {
		if ( str == null || str.isEmpty() ) {
			return str;
		}

		StringBuilder sb = new StringBuilder();
		int start = 0;
		int end = str.length();

		Matcher matcher = PROPERTY_PATTERN.matcher(str);
		while ( matcher.find() ) {
			end = matcher.start(PROPERTY_GROUP_PLACEHOLDER);
			sb.append(str.subSequence(start, end));

			start = matcher.end(PROPERTY_GROUP_PLACEHOLDER);
			end = str.length();

			String key = matcher.group(PROPERTY_GROUP_KEY);
			String val = System.getProperty(key);

			if ( val != null ) {
				sb.append(val);
			}
			else {
				sb.append("#{");
				sb.append(key);
				sb.append("}");
			}
		}

		if ( start < end ) {
			sb.append(str.subSequence(start, end));
		}

		return sb.toString();
	}

	protected static void close(Writer writer) {
		try {
			if ( writer != null ) {
				writer.flush();
				writer.close();
			}
		}
		catch (IOException e) {
			e.printStackTrace();
		}
	}

	protected static void close(Reader reader) {
		try {
			if ( reader != null ) {
				reader.close();
			}
		}
		catch (IOException e) {
			e.printStackTrace();
		}
	}

}
